home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / Miro_Downloader.exe / template.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-11-12  |  18.3 KB  |  526 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. import os
  5. import config
  6. import eventloop
  7. from templatehelper import quoteattr, escape, attrPattern, rawAttrPattern, resourcePattern, generateId
  8. from templateoptimize import HTMLChangeOptimizer
  9. from xhtmltools import urlencode
  10. from template_compiler import checkU
  11. from itertools import chain
  12. import logging
  13. import util
  14. import re
  15. HTMLPattern = re.compile('^.*<body.*?>(.*)</body\\s*>', re.S)
  16. if os.environ.has_key('DEMOCRACY_RECOMPILE_TEMPLATES'):
  17.     import template_compiler
  18.     import resources
  19.     template_compiler.setResourcePath(resources.path(''))
  20.  
  21.  
  22. def fillTemplate(filename, domHandler, platform, eventCookie, bodyTagExtra = '', top = True, onlyBody = False, *args, **kargs):
  23.     if os.environ.has_key('DEMOCRACY_RECOMPILE_TEMPLATES'):
  24.         (tcc, handle) = template_compiler.compileTemplate(filename)
  25.         exec tcc.getOutput() in locals()
  26.         return fillTemplate(domHandler, platform, eventCookie, bodyTagExtra, *args, **kargs)
  27.     else:
  28.         filename = filename.replace('/', '.').replace('\\', '.').replace('-', '_')
  29.         components = filename.split('.')
  30.         mod = __import__('compiled_templates.%s' % filename)
  31.         for comp in components:
  32.             mod = getattr(mod, comp)
  33.         
  34.         return mod.fillTemplate(domHandler, platform, eventCookie, bodyTagExtra, *args, **kargs)
  35.  
  36.  
  37. def fillStaticTemplate(filename, platform = '', eventCookie = 'noCookie', bodyTagExtra = '', onlyBody = False, *args, **kargs):
  38.     (tch, handle) = fillTemplate(filename, None, platform, eventCookie, bodyTagExtra, *args, **kargs)
  39.     handle.unlinkTemplate()
  40.     rv = tch.read()
  41.     if onlyBody:
  42.         rv = HTMLPattern.match(rv).group(1)
  43.     
  44.     return rv
  45.  
  46.  
  47. def queueDOMChange(func, name):
  48.     """Queue function that does a bunch of DOM updates to a display.
  49.  
  50.     What happens is a little weird, we queue a call in the main gui thread
  51.     loop, then we queue a second call in the backend loop.  If that call does
  52.     any DOM updates like changeItems, addItemBefore, etc., those will almost
  53.     certainly be queued back into the main loop.
  54.  
  55.     The rational for this is that if the main loop is busy it's better to wait
  56.     for it to be idle if we have a bunch of changes.  That way we can group
  57.     things together and have them happen all at once.  This may seem like it
  58.     adds a bunch of latency, but this doesn't seem to be the case,
  59.     addUrgentCall() happens quickly and if we are waiting on the gui thread,
  60.     that means we're doing some other kind of gui update.
  61.     """
  62.     import frontend
  63.     
  64.     try:
  65.         (None, frontend.inMainThread)((lambda : eventloop.addUrgentCall(func, name)))
  66.     except:
  67.         eventloop.addIdle(func, name)
  68.  
  69.  
  70.  
  71. def queueSelectDisplay(frame, display, area):
  72.     '''Queue a call to MainFrame.selectDisplay using queueDOMChange.  This is
  73.     useful if you want it to happen after template DOM updates (see
  74.     selection.py for an example).
  75.     '''
  76.     if area in toSelect:
  77.         toSelect[area].unlink()
  78.     
  79.     toSelect[area] = display
  80.     (None, queueDOMChange)((lambda : doSelectDisplay(frame, area)), 'Select display')
  81.  
  82. toSelect = { }
  83.  
  84. def doSelectDisplay(frame, area):
  85.     if area in toSelect:
  86.         frame.selectDisplay(toSelect.pop(area), area)
  87.     
  88.  
  89.  
  90. class TrackedView:
  91.     
  92.     def __init__(self, anchorId, anchorType, view, templateFunc, parent, name):
  93.         self.anchorId = anchorId
  94.         self.anchorType = anchorType
  95.         self.view = view
  96.         self.templateFunc = templateFunc
  97.         self.parent = parent
  98.         self.htmlChanger = parent.htmlChanger
  99.         self.name = name
  100.         self.toChange = { }
  101.         self.toRemove = []
  102.         self.toAdd = []
  103.         self.addBefore = None
  104.         self.idle_queued = False
  105.  
  106.     
  107.     def tid(self, obj):
  108.         return 'objid-%s-%d' % (id(self), id(obj))
  109.  
  110.     
  111.     def initialFillIn(self):
  112.         self.view.confirmDBThread()
  113.         self.toChange = { }
  114.         self.toRemove = []
  115.         self.toAdd = []
  116.         self.addBefore = None
  117.         self.addObjects(self.view)
  118.         self.view.addChangeCallback(self.onChange)
  119.         self.view.addAddCallback(self.onAdd)
  120.         self.view.addResortCallback(self.onResort)
  121.         self.view.addRemoveCallback(self.onRemove)
  122.  
  123.     
  124.     def onUnlink(self):
  125.         self.view.removeChangeCallback(self.onChange)
  126.         self.view.removeAddCallback(self.onAdd)
  127.         self.view.removeResortCallback(self.onResort)
  128.         self.view.removeRemoveCallback(self.onRemove)
  129.  
  130.     
  131.     def initialXML(self, item):
  132.         xml = self.currentXML(item)
  133.         self.htmlChanger.setInitialHTML(self.tid(item), xml)
  134.         return xml
  135.  
  136.     
  137.     def currentXML(self, item):
  138.         xml = self.templateFunc(item, self.name, self.view, self.tid(item)).read()
  139.         return xml
  140.  
  141.     
  142.     def callback(self):
  143.         self.toChange = { }
  144.         self.toRemove = []
  145.         self.toAdd = []
  146.         self.addBefore = None
  147.         self.idle_queued = False
  148.  
  149.     
  150.     def addCallback(self):
  151.         if not self.idle_queued:
  152.             queueDOMChange(self.callback, 'TrackedView DOM Change (%s)' % self.name)
  153.             self.idle_queued = True
  154.         
  155.  
  156.     
  157.     def onResort(self):
  158.         self.toChange = { }
  159.         self.toRemove = []
  160.         self.toAdd = []
  161.         self.addBefore = None
  162.         self.addObjects(self.view)
  163.  
  164.     
  165.     def onChange(self, obj, id):
  166.         if obj in self.toAdd:
  167.             return None
  168.         
  169.         self.toChange[id] = obj
  170.         self.addCallback()
  171.  
  172.     
  173.     def onAdd(self, obj, id):
  174.         if len(self.toChange) > 0 or len(self.toRemove) > 0:
  175.             self.callback()
  176.         
  177.         if self.parent.domHandler:
  178.             next = self.view.getNextID(id)
  179.             if next is not None:
  180.                 nextTid = self.tid(self.view.getObjectByID(next))
  181.             else:
  182.                 nextTid = None
  183.             for i in range(len(self.toAdd)):
  184.                 if self.tid(self.toAdd[i]) == nextTid:
  185.                     self.toAdd.insert(i, obj)
  186.                     self.addCallback()
  187.                     return None
  188.                     continue
  189.             
  190.             if len(self.toAdd) > 0 and nextTid == self.addBefore:
  191.                 self.toAdd.append(obj)
  192.                 self.addCallback()
  193.             else:
  194.                 self.callback()
  195.                 self.toAdd.append(obj)
  196.                 self.addBefore = nextTid
  197.                 self.addCallback()
  198.         
  199.  
  200.     
  201.     def addObjects(self, objects):
  202.         '''Insert the XML for a list of objects into the DOM tree.'''
  203.         if len(objects) == 0:
  204.             return None
  205.         
  206.         xmls = [ self.initialXML(x) for x in objects ]
  207.         for xmls_part in util.partition(xmls, 100):
  208.             self.addXML(''.join(xmls_part))
  209.         
  210.  
  211.     
  212.     def addXML(self, xml):
  213.         if self.addBefore:
  214.             self.parent.domHandler.addItemBefore(xml, self.addBefore)
  215.         elif self.anchorType in ('parentNode', 'containerDiv'):
  216.             self.parent.domHandler.addItemAtEnd(xml, self.anchorId)
  217.         
  218.         if self.anchorType == 'nextSibling':
  219.             self.parent.domHandler.addItemBefore(xml, self.anchorId)
  220.         
  221.  
  222.     
  223.     def onRemove(self, obj, id):
  224.         if obj in self.toAdd:
  225.             self.toAdd.remove(obj)
  226.             return None
  227.         
  228.         if len(self.toAdd) > 0:
  229.             self.callback()
  230.         
  231.         if id in self.toChange:
  232.             del self.toChange[id]
  233.         
  234.         self.toRemove.append(obj)
  235.         self.addCallback()
  236.  
  237.  
  238.  
  239. class UpdateRegionBase:
  240.     '''Base class for UpdateRegion and ConfigUpdateRegion.  Subclasses must
  241.     define renderXML, which returns a string representing the up-to-date XML
  242.     for this region.  Also, hookupCallbacks() which hooks up any callbacks
  243.     needed.  Subclasses can use onChange() as the handler for any callbacks.
  244.     '''
  245.     
  246.     def __init__(self, anchorId, anchorType, templateFunc, parent):
  247.         self.anchorId = anchorId
  248.         self.anchorType = anchorType
  249.         self.templateFunc = templateFunc
  250.         self.parent = parent
  251.         self.htmlChanger = self.parent.htmlChanger
  252.         self.tid = generateId()
  253.         self.idle_queued = False
  254.  
  255.     
  256.     def initialFillIn(self):
  257.         if self.parent.domHandler:
  258.             self.parent.domHandler.addItemBefore(self.initialXML(), self.anchorId)
  259.         
  260.         self.hookupCallbacks()
  261.  
  262.     
  263.     def initialXML(self):
  264.         xml = self.renderXML()
  265.         self.htmlChanger.setInitialHTML(self.tid, xml)
  266.         return xml
  267.  
  268.     
  269.     def onChange(self, *args, **kwargs):
  270.         if not self.idle_queued:
  271.             queueDOMChange(self.doChange, 'UpdateRegion DOM Change (%s)' % self.name)
  272.             self.idle_queued = True
  273.         
  274.  
  275.     
  276.     def doChange(self):
  277.         xml = self.renderXML()
  278.         changes = self.parent.htmlChanger.calcChanges(self.tid, xml)
  279.         if changes and self.parent.domHandler:
  280.             self.parent.domHandler.changeItems(changes)
  281.         
  282.         self.idle_queued = False
  283.  
  284.  
  285.  
  286. class UpdateRegion(UpdateRegionBase):
  287.     
  288.     def __init__(self, anchorId, anchorType, view, templateFunc, parent, name):
  289.         UpdateRegionBase.__init__(self, anchorId, anchorType, templateFunc, parent)
  290.         self.view = view
  291.         self.name = name
  292.  
  293.     
  294.     def renderXML(self):
  295.         return self.templateFunc(self.name, self.view, self.tid).read()
  296.  
  297.     
  298.     def hookupCallbacks(self):
  299.         self.view.addChangeCallback(self.onChange)
  300.         self.view.addAddCallback(self.onChange)
  301.         self.view.addRemoveCallback(self.onChange)
  302.         self.view.addResortCallback(self.onChange)
  303.         self.view.addViewChangeCallback(self.onChange)
  304.  
  305.     
  306.     def onUnlink(self):
  307.         self.view.removeChangeCallback(self.onChange)
  308.         self.view.removeAddCallback(self.onChange)
  309.         self.view.removeRemoveCallback(self.onChange)
  310.         self.view.removeResortCallback(self.onChange)
  311.         self.view.removeViewChangeCallback(self.onChange)
  312.  
  313.  
  314.  
  315. class ConfigUpdateRegion(UpdateRegionBase):
  316.     
  317.     def __init__(self, anchorId, anchorType, templateFunc, parent):
  318.         UpdateRegionBase.__init__(self, anchorId, anchorType, templateFunc, parent)
  319.         self.name = 'ConfigUpdateRegion'
  320.  
  321.     
  322.     def hookupCallbacks(self):
  323.         config.addChangeCallback(self.onChange)
  324.  
  325.     
  326.     def onUnlink(self):
  327.         config.removeChangeCallback(self.onChange)
  328.  
  329.     
  330.     def renderXML(self):
  331.         return self.templateFunc(self.tid).read()
  332.  
  333.  
  334.  
  335. class Handle:
  336.     
  337.     def __init__(self, domHandler, templateVars, document = None, onUnlink = (lambda : None)):
  338.         self.domHandler = domHandler
  339.         self.templateVars = templateVars
  340.         self.document = document
  341.         self.trackedHides = { }
  342.         self.trackedViews = []
  343.         self.updateRegions = []
  344.         self.subHandles = []
  345.         self.triggerActionURLsOnLoad = []
  346.         self.triggerActionURLsOnUnload = []
  347.         self.onUnlink = onUnlink
  348.         self.htmlChanger = HTMLChangeOptimizer()
  349.         self.filled = False
  350.  
  351.     
  352.     def addTriggerActionURLOnLoad(self, url):
  353.         self.triggerActionURLsOnLoad.append(str(url))
  354.  
  355.     
  356.     def addTriggerActionURLOnUnload(self, url):
  357.         self.triggerActionURLsOnUnload.append(str(url))
  358.  
  359.     
  360.     def getTriggerActionURLsOnLoad(self):
  361.         return self.triggerActionURLsOnLoad
  362.  
  363.     
  364.     def getTriggerActionURLsOnUnload(self):
  365.         return self.triggerActionURLsOnUnload
  366.  
  367.     
  368.     def getTemplateVariable(self, name):
  369.         return self.templateVars[name]
  370.  
  371.     
  372.     def addUpdateHideOnView(self, id, view, hideFunc, previous):
  373.         
  374.         checkFunc = lambda *args: self._checkHide(id)
  375.         self.trackedHides[id] = (view, hideFunc, checkFunc, previous)
  376.         if self.filled:
  377.             self.addHideChecks(view, checkFunc)
  378.         
  379.  
  380.     
  381.     def _checkHide(self, id):
  382.         (view, hideFunc, checkFunc, previous) = self.trackedHides[id]
  383.         if hideFunc() != previous:
  384.             self.trackedHides[id] = (view, hideFunc, checkFunc, not previous)
  385.             if previous:
  386.                 self.domHandler.showItem(id)
  387.             else:
  388.                 self.domHandler.hideItem(id)
  389.         
  390.  
  391.     
  392.     def addView(self, anchorId, anchorType, view, templateFunc, name):
  393.         tv = TrackedView(anchorId, anchorType, view, templateFunc, self, name)
  394.         self.trackedViews.append(tv)
  395.  
  396.     
  397.     def addUpdate(self, anchorId, anchorType, view, templateFunc, name):
  398.         ur = UpdateRegion(anchorId, anchorType, view, templateFunc, self, name)
  399.         self.updateRegions.append(ur)
  400.  
  401.     
  402.     def forceUpdate(self):
  403.         for ur in self.updateRegions:
  404.             ur.onChange()
  405.         
  406.         for h in self.subHandles:
  407.             h.forceUpdate()
  408.         
  409.  
  410.     
  411.     def addConfigUpdate(self, anchorId, anchorType, templateFunc):
  412.         ur = ConfigUpdateRegion(anchorId, anchorType, templateFunc, self)
  413.         self.updateRegions.append(ur)
  414.  
  415.     
  416.     def unlinkTemplate(self, top = True):
  417.         self.domHandler = None
  418.         
  419.         try:
  420.             self.document.unlink()
  421.         except:
  422.             pass
  423.  
  424.         self.document = None
  425.         for o in chain(self.trackedViews, self.updateRegions):
  426.             o.onUnlink()
  427.         
  428.         self.trackedViews = []
  429.         self.updateRegions = []
  430.         if self.filled:
  431.             for id in self.trackedHides.keys():
  432.                 (view, hideFunc, checkFunc, previous) = self.trackedHides[id]
  433.                 self.removeHideChecks(view, checkFunc)
  434.             
  435.         
  436.         self.trackedHides = { }
  437.         for handle in self.subHandles:
  438.             handle.unlinkTemplate()
  439.         
  440.         self.subHandles = []
  441.         self.templateVars.clear()
  442.         self.onUnlink()
  443.  
  444.     
  445.     def initialFillIn(self):
  446.         for ur in self.updateRegions:
  447.             ur.initialFillIn()
  448.         
  449.         for tv in self.trackedViews:
  450.             tv.initialFillIn()
  451.         
  452.         for handle in self.subHandles:
  453.             handle.initialFillIn()
  454.         
  455.         for id in self.trackedHides.keys():
  456.             (view, hideFunc, checkFunc, previous) = self.trackedHides[id]
  457.             self.addHideChecks(view, checkFunc)
  458.         
  459.         self.filled = True
  460.  
  461.     
  462.     def addHideChecks(self, view, checkFunc):
  463.         logging.debug('Add hide checks: function %s on view %s', checkFunc, view)
  464.         view.addChangeCallback(checkFunc)
  465.         view.addAddCallback(checkFunc)
  466.         view.addRemoveCallback(checkFunc)
  467.         view.addResortCallback(checkFunc)
  468.         view.addViewChangeCallback(checkFunc)
  469.         checkFunc()
  470.  
  471.     
  472.     def removeHideChecks(self, view, checkFunc):
  473.         logging.debug('Remove hide checks: function %s on view %s', checkFunc, view)
  474.         view.removeChangeCallback(checkFunc)
  475.         view.removeAddCallback(checkFunc)
  476.         view.removeRemoveCallback(checkFunc)
  477.         view.removeResortCallback(checkFunc)
  478.         view.removeViewChangeCallback(checkFunc)
  479.  
  480.     
  481.     def addSubHandle(self, handle):
  482.         self.subHandles.append(handle)
  483.  
  484.  
  485.  
  486. def returnFalse(x):
  487.     return False
  488.  
  489.  
  490. def returnTrue(x):
  491.     return True
  492.  
  493.  
  494. def identityFunc(x):
  495.     return x
  496.  
  497.  
  498. def nullSort(x, y):
  499.     return 0
  500.  
  501.  
  502. def quoteAndFillAttr(value, localVars):
  503.     checkU(value)
  504.     return ''.join(('"', quoteattr(fillAttr(value, localVars)), '"'))
  505.  
  506.  
  507. def fillAttr(_value, _localVars):
  508.     checkU(_value)
  509.     match = attrPattern.match(_value)
  510.     if match:
  511.         result = eval(match.group(2), globals(), _localVars)
  512.         return ''.join((match.group(1), urlencode(result), match.group(3)))
  513.     else:
  514.         match = rawAttrPattern.match(_value)
  515.         if match:
  516.             result = eval(match.group(2), globals(), _localVars)
  517.             return ''.join((match.group(1), result, match.group(3)))
  518.         else:
  519.             match = resourcePattern.match(_value)
  520.             if match:
  521.                 return resources.url(match.group(1))
  522.             else:
  523.                 return _value
  524.  
  525. import compiled_templates
  526.